<template>
  <n-card
      class="h-full"
      :content-style="{ padding: '5px' }"
      :header-style="{ padding: '5px' }"
      :segmented="true"
  >
    <template #header>
      <div class="flex items-center">
        <n-input class="mr-2" v-model:value="pattern" placeholder="搜索" size="small" />
        <n-button type="primary" size="small" @click="onAddGoal">添加</n-button>
        <n-switch size="small" v-model:value="expandAllFlag" />
      </div>
    </template>
    <n-tree
        :expanded-keys="getExpandedKeys"
        block-line
        :pattern="pattern"
        :data="departmentData"
        :node-props="nodeProps"
        selectable
        draggable
        @drop="handleDrop"
        :on-update:expanded-keys="onUpdateExpandedKeys"
    />
    <ModalDialog ref="modalDialogRef" @confirm="onDataFormConfirm" contentHeight="100vh">
      <template #content>
        <DataForm ref="dataFormRef" :options="formItems" :form-config="formConfig"/>
      </template>
    </ModalDialog>
    <n-dropdown
        placement="bottom-start"
        trigger="manual"
        :x="xRef"
        :y="yRef"
        :options="options"
        :show="showDropdownRef"
        :on-clickoutside="onClickoutside"
        @select="handleSelect"
    />
  </n-card>

</template>

<script lang="ts" setup>
import {post, Response} from '@/api/http'
import {
  addGoal,
  addLifeModeItems, changeGoalsList,
  changeGoalState,
  deleteGoal,
  getGoalsList,
  getTableList,
  startLifeMode
} from '@/api/url'
import {DataTableColumn, FormProps, NAvatar, useDialog, useMessage, NSlider, NInput, NTime, TreeOption} from 'naive-ui'
import {computed, defineComponent, h, nextTick, onMounted, reactive, ref, shallowReactive, watch} from 'vue'
import useUserStore from "@/store/modules/user";
import { DataFormType, ModalDialogType, FormItem } from '@/types/components'
import UseSurfaceSettingStore from "@/store/modules/surfaceSetting";
import {renderTag, renderTimePicker} from "@/hooks/form";
import {TableActionModel, usePagination, useRenderAction, useRowKey, useTable, useTableColumn} from "@/hooks/table";
import { NIcon, NTree, TreeDropInfo, NButton } from "naive-ui";
import {obj2Map, stringify} from "@/utils";
import {UseConstsStore} from "@/store/modules/consts";
import surfaceSetting from "@/store/modules/surfaceSetting";

const userStore = useUserStore()
const useConsts = UseConstsStore()
const useSurfaceSetting = UseSurfaceSettingStore()
const message = useMessage()
const naiveDialog = useDialog()

interface GoalData {
  id?:number
  goalName?:string
  goalDesc?:string
  state?:number
  lastStartTime?:number
  timePeriods?:Array<number>
  goalScore?:number
  goalConclusion?:string
}

const pattern= ref('');
const key = ref(new Date().getTime());
const departmentData = ref<Array<{key:number,label:number|string,childern?:Array<object>}>>([])
const stateMap = computed(()=>{
  return obj2Map(useConsts.getConsts().stateMap);
})

// 获取数据
async function doRefresh() {
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: getGoalsList,
      token:userStore.getToken()
    });
    const treeData = new Map(Object.entries(data.data.data));
    // console.log(treeData)
    departmentData.value = []
    for (const treeDataKey of treeData.keys()) {
      const father = {
        label:stateMap.value.get(treeDataKey) ,
        key: parseInt(treeDataKey),
        children: (treeData.get(treeDataKey) as Array<object>).map((i: any) => {
          return {
            label: i.goalName,
            key: i.id,
            ...i
          }
        })
      }
      departmentData.value.push(father)
      // message.success(data.msg)
    }
    // console.log(departmentData)
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    // table.tableLoading.value = false;
  }
}
onMounted(doRefresh)
watch(key,doRefresh)
watch(stateMap,doRefresh)
// 下拉菜单
let chooseRow:GoalData|null = null;
const options = [
  {
    label: "查看阶段",
    key: "show",
  },
  {
    label: "启动目标",
    key: "start",
  },
  {
    label: "暂停目标",
    key: "stop",
  },
  {
    label: "结束目标",
    key: "finish",
  },
  {
    label: "编辑",
    key: "edit",
  },
  {
    label: () => h("span", { style: { color: "red" } }, "删除"),
    key: "delete",
  },
];
const showDropdownRef = ref(false);
const xRef = ref(0);
const yRef = ref(0);
const onClickoutside = () => {
  showDropdownRef.value = false;
};
function onFinishGoal(params: GoalData|null, str:string, newState:number){
  if(params){
    const func = async (id:number|undefined,beginTime:number, endTime:number|null,
                        oldState:number|undefined,newState:number) => {
      try {
        const data : Response = await post({
          url: changeGoalState,
          data: {id:id,startTime:beginTime,endTime:endTime,oldState:oldState,newState:newState},
          token:userStore.getToken()
        });
        // console.log(data)
        message.success(data.msg)
      }catch(e) {
        message.error((e as Error).message)
      }finally {
        key.value = Date.now()
      }
    }
    naiveDialog.warning({
      title: '提示',
      content: '是否要选择'+str+'该目标:'+params.goalName+'？',
      positiveText: '记录上一段的时间',
      negativeText: '取消上一段的时间',
      onNegativeClick:()=>{
        func(params.id,Date.now(),null,params.state,newState)
      },
      onPositiveClick:() => {
        func(params.id,Date.now(),Date.now(),params.state,newState)
      },
    })
  }
}
const handleSelect = (key: string, node: string) => {
  // console.log(key, node);
  showDropdownRef.value = false;
  const str = key==='start'?'开启':key==='stop'?'暂停':'结束';
  if(key == "show"){
    if(chooseRow?.id)
      useSurfaceSetting.addIdToArray(chooseRow.id,useSurfaceSetting.getSurfaceSetting().showGoalId)
    //console.log(useSurfaceSetting.getSurfaceSetting().showGoalId)
  }
  if (key == "edit") {
    onUpdateGoal(chooseRow)
  }
  if (key == "delete") {
    onDeleteGoal(chooseRow)
  }
  if (key == "start") {
    onFinishGoal(chooseRow,str,0)
  }
  if (key == "stop") {
    onFinishGoal(chooseRow,str,1)
  }
  if (key == "finish") {
    onFinishGoal(chooseRow,str,3)
  }
};

// 事件
const nodeProps = ({ option }: { option: TreeOption }) => {
  // @contextmenu.prevent.stop="click2FieldSetting"
  //   @click="click2Field"
  return {
    // 左击
    onClick() {
      // onClick(e)
      if (!option.children && !option.disabled) {
        // message.info('[Click] ' + option.label)
        // console.log("onClick");
      }
    },
    // 双击
    ondblclick(e: MouseEvent) {
      if (option.children === undefined && option.key !== undefined) {
        // editSettings.toDealRowId = parseInt(option.key.toString());
        showDropdownRef.value = true;
        xRef.value = e.clientX;
        yRef.value = e.clientY;
        chooseRow = {...option} as GoalData;
        // deleteIdHasChild = option.children?.length > 0;
      }
    },
    // 右击
    onContextmenu(e: MouseEvent) {
      //取消默认的浏览器自带右键
      e.preventDefault();
      if (option.children === undefined && option.key !== undefined) {
        // editSettings.toDealRowId = parseInt(option.key.toString());
        showDropdownRef.value = true;
        xRef.value = e.clientX;
        yRef.value = e.clientY;
        chooseRow = {...option} as GoalData;
        // deleteIdHasChild = option.children?.length > 0;
      }
    },
  };
};

// 添加表单
const formConfig = {
  labelWidth: 100,
  size: 'medium',
  labelAlign: 'right',
} as FormProps
const formItems = [
  {
    label: 'id',
    type: 'input',
    key: 'id',
    hidden:true,
    disabled:true,
    value: ref(null),
    render: (formItem) => {
      return h(NInput, {
        hidden:true,
        disabled:true,
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
      })
    },
  },
  {
    label: '目标名',
    type: 'input',
    key: 'goalName',
    value: ref(null),
    validator: (formItem, message) => {
      if (!formItem.value.value) {
        message.error('请输入目标名')
        return false
      }
      return true
    },
    render: (formItem) => {
      return h(NInput, {
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
        placeholder: '请输入目标名',
      })
    },
  },
  {
    label: '描述',
    key: 'goalDesc',
    value: ref(null),
    maxLength: 500,
    inputType: 'text',
    validator: (formItem, message) => {
      if (!formItem.value.value) {
        message.error('请输入角色名称')
        return false
      }
      return true
    },
    render: (formItem) => {
      return h(NInput, {
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
        placeholder: '请输入角色描述',
        type: 'textarea',
        rows: 5,
      })
    },
  },
  {
    label: '目标满意分数',
    type: 'input',
    key: 'goalScore',
    value: ref(0),
    validator: (formItem, message) => {
      if (!formItem.value.value) {
        message.error('请输入目标名')
        return false
      }
      return true
    },
    render: (formItem) => {
      return h(NSlider, {
        value: formItem.value.value,
        step:1,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
        placeholder: '请输入分数',
      })
    },
  },
  {
    label: '目标总结',
    key: 'goalConclusion',
    value: ref(null),
    maxLength: 500,
    inputType: 'text',
    validator: (formItem, message) => {
      if (!formItem.value.value) {
        message.error('请输入角色名称')
        return false
      }
      return true
    },
    render: (formItem) => {
      return h(NInput, {
        value: formItem.value.value,
        onUpdateValue: (val) => {
          formItem.value.value = val
        },
        placeholder: '请输入角色描述',
        type: 'textarea',
        rows: 5,
      })
    },
  },
] as FormItem[]
let toAddGoal = 0;
const modalDialogRef = ref<ModalDialogType | null>(null)
const dataFormRef = ref<DataFormType | null>(null)

async function onDataFormConfirm() {
  if (dataFormRef.value?.validator()) {
    modalDialogRef.value?.toggle()
    if(toAddGoal === 0){
      await addNewGoal({...dataFormRef.value.generatorParams(), state:1})
    }else {
      await addNewGoal({...dataFormRef.value.generatorParams(), state:chooseRow?.state})
    }

  }
}
const addNewGoal = async (params:any)=>{
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: addGoal,
      data: params,
      token:userStore.getToken()
    });
    // console.log(data)
    message.success(data.msg)
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    key.value = new Date().getTime();
  }
}
// 操作
function onAddGoal() {
  toAddGoal = 0;
  modalDialogRef.value?.toggle()
  nextTick(() => {
    dataFormRef.value?.reset()
  })
}
function onUpdateGoal(item: any) {
  // console.log(item)
  toAddGoal = 1;
  modalDialogRef.value?.toggle()
  nextTick(() => {
    formItems.forEach((it) => {
      const key = it.key
      const propName = item[key]
      console.log(item)
      if (propName) {
        it.value.value = propName
      }
    })
  })
}
function onDeleteGoal(params: GoalData|null) {
  toAddGoal = 2;
  naiveDialog.warning({
    title: '提示',
    content: '是否要删除？',
    positiveText: '删除',
    onPositiveClick:async () => {
      try {
        // table.tableLoading.value = true;
        const data: Response = await post({
          url: deleteGoal,
          data: params,
          token:userStore.getToken()
        });
        // console.log(data)
        message.success(data.msg)
      }catch(e) {
        message.error((e as Error).message)
      }finally {
        key.value = new Date().getTime();
      }
    },
  })
}

// 展开
const expandAllFlag = ref(false)
const getExpandedKeys = shallowReactive(useSurfaceSetting.getSurfaceSetting().goalExpandKeys)
function onUpdateExpandedKeys(keys: any) {
  getExpandedKeys.length = 0
  getExpandedKeys.push(...keys)
  // console.log(getExpandedKeys)
  useSurfaceSetting.getSurfaceSetting().goalExpandKeys = [...getExpandedKeys]
}
watch(() => expandAllFlag.value,
    (newVal) => {newVal
        ? getExpandedKeys.push(...departmentData.value.map((it) => it.key))
        : (getExpandedKeys.length = 0)
    }
)

// 移动
function findSiblingsAndIndex(node: TreeOption, nodes?: any[]): [TreeOption[], number] | [null, null] {
  if (!nodes) return [null, null];
  for (let i = 0; i < nodes.length; ++i) {
    const siblingNode = nodes[i];
    if (siblingNode.key === node.key) return [nodes, i];
    const [siblings, index] = findSiblingsAndIndex(node, siblingNode.children);
    if (siblings && index !== null) return [siblings, index];
  }
  return [null, null];
}
const handleDrop = async ({ node, dragNode, dropPosition }: TreeDropInfo) => {
  const data =departmentData;
  const [dragNodeSiblings, dragNodeIndex] = findSiblingsAndIndex(dragNode, data.value);
  // console.log('dragNodeSiblings',dragNodeSiblings,dragNode,data);
 // console.log(dropPosition,node.key,node?.state,dragNode?.state)
  if (dragNodeSiblings === null || dragNodeIndex === null) return;
  if (dropPosition === "inside" && node.key === dragNode?.state) {
    dragNodeSiblings.splice(dragNodeIndex, 1);
    // console.log("inside");
    if (node.children) {
      node.children.unshift(dragNode);
    }
  } else if (dropPosition === "before" && node.state!==undefined && node.state === dragNode?.state) {
    dragNodeSiblings.splice(dragNodeIndex, 1);
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, data.value);
    if (nodeSiblings === null || nodeIndex === null) return;
    nodeSiblings.splice(nodeIndex, 0, dragNode);
  } else if (dropPosition === "after" && node.state!==undefined && node.state === dragNode?.state) {
    dragNodeSiblings.splice(dragNodeIndex, 1);
    const [nodeSiblings, nodeIndex] = findSiblingsAndIndex(node, data.value);
    if (nodeSiblings === null || nodeIndex === null ) return;
    nodeSiblings.splice(nodeIndex + 1, 0, dragNode);
  } else return;
  //console.log("++++++++++++====+++++",JSON.parse(JSON.stringify(data.value)))
  const original = getOrignalData(JSON.parse(JSON.stringify(data.value)));
  // console.log("+++++++++++++++++",original,stringify(original))
  try {
    // table.tableLoading.value = true;
    const data: Response = await post({
      url: changeGoalsList,
      data: {goalsList:stringify(original)},
      token:userStore.getToken()
    });
  }catch(e) {
    message.error((e as Error).message)
  }finally {
    key.value = new Date().getTime();
  }
  // fieldTree.setFieldIdDataList(original);
  //console.log("handleDrop",fieldTree)
};
const getOrignalData = (arg: Array<any>) => {
  const map = new Map<number, Array<number>>
  if(arg) for (const resultElement of arg) {
    map.set(resultElement.key, resultElement.children.map(c=>c.key))
  }
  return map;
};
</script>
<style lang="scss" scoped>
.avatar-container {
  position: relative;
  width: 30px;
  margin: 0 auto;
  vertical-align: middle;
  .avatar {
    width: 100%;
    border-radius: 50%;
  }
  .avatar-vip {
    border: 2px solid #cece1e;
  }
  .vip {
    position: absolute;
    top: 0;
    right: -9px;
    width: 15px;
    transform: rotate(60deg);
  }
}
.gender-container {
  .gender-icon {
    width: 20px;
  }
}
</style>